package com.wwz.config;

import com.wwz.annotation.BusinessJudge;
import com.wwz.BusUtils;
import com.wwz.CallBackMethod;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author wwz
 */
@Aspect
@Component
public class WebMvcConfig {
    private final static Logger log = LoggerFactory.getLogger(WebMvcConfig.class);
    private static ExecutorService executorService = new ThreadPoolExecutor(10,20,5000L, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(10));
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedisLuaTemplate redisLuaTemplate;
    @Pointcut(value="@annotation(com.wwz.annotation.BusinessJudge)")
    public void pointcut(){
    }

    @Around(value ="pointcut()" )
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
            Method method = methodSignature.getMethod();
            if(method.isAnnotationPresent(BusinessJudge.class)){
                BusinessJudge businessJudge = method.getAnnotation(BusinessJudge.class);
                return BusUtils.postProcess(proceedingJoinPoint,redisLuaTemplate,new CallBackMethod() {
                    @Override
                    public Object postProcess(ProceedingJoinPoint proceedingJoinPoint, RedisLuaTemplate redisLuaTemplate) throws Throwable {
                        if(redisLuaTemplate.isHaveProduct("orders:keyprefix:orderId",10)&&redisLuaTemplate.lock(businessJudge.key(),"3",60)) {
                           try{
                             return  proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
                           }catch (Exception e){

                           }finally {
                               redisLuaTemplate.unLock(businessJudge.key(),"3");
                           }
                        }else{
                            log.error("商品抢购完");
                            return "商品抢购完";
                        }
                        return null;

                    }
                });

            } else{
              return  proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
            }
    }




    abstract  class   Callback{
      abstract  void method();
        public Callback(ProceedingJoinPoint proceedingJoinPoint){

        }
    }

}
